#include <iostream>
#include <unistd.h>
#include <semaphore.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <pthread.h>

using namespace std;

// s1 司机: 车门关闭开车 -> 行驶
// s2 售票员: 车停下开门 -> 售票

sem_t s1;
sem_t s2;

class Sem
{
public:
    Sem(sem_t sem, int num)
        : _sem(sem)
    {
        sem_init(&_sem, 0, num); // 初始化
    }

    void P()
    {
        sem_wait(&_sem); // 申请信号量
    }

    void V()
    {
        sem_post(&_sem); // 释放信号量
    }

    ~Sem()
    {
        sem_destroy(&_sem); // 清理
    }

private:
    sem_t _sem;
};

Sem sem1(s1, 1);
Sem sem2(s2, 1);

void Drive()
{
    sleep(1);
    sem1.P();
    cout << "启动车辆" << endl;
    cout << "正常行车" << endl;
    cout << "到站停车" << endl;
    sem2.V();
}
void Sell()
{
    sem2.P();
    cout << "开车门" << endl;
    cout << "售票" << endl;
    cout << "关车门" << endl;
    sem1.V();
}

int main()
{
    pid_t id = fork();
    if (id == 0)
    {
        // 子进程 - 司机
        while (true)
        {
            Drive();
        }
        exit(0);
    }
    // 父进程 - 售票员
    while (true)
    {
        Sell();
    }
    wait(nullptr);
    return 0;
}

// int main()
// {
//     pthread_t tid1, tid2;
//     pthread_create(&tid1, nullptr, Drive, nullptr);
//     pthread_create(&tid2, nullptr, Sell, nullptr);

//     pthread_join(tid1, nullptr);
//     pthread_join(tid2, nullptr);

//     return 0;
// }

// pthread_cond_t gcond = PTHREAD_COND_INITIALIZER;//条件变量
// pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;//互斥锁

// void *Drive(void *args)
// {
//     while(true)
//     {
//         sleep(1);
//         cout << "启动车辆" << endl;
//         cout << "正常行车" << endl;
//         cout << "到站停车" << endl;
//         pthread_cond_signal(&gcond);
//     }
// 	pthread_exit((void*)0);
// }
// void *Sell(void *args)
// {
//     while(true)
//     {
//         pthread_mutex_lock(&gmutex);
//         pthread_cond_wait(&gcond, &gmutex);
//         cout << "开车门" << endl;
//         cout << "售票" << endl;
//         cout << "关车门" << endl;
//         pthread_mutex_unlock(&gmutex);
//     }
// 	pthread_exit((void*)0);
// }

// int main()
// {
//     pthread_t tid1, tid2;
//     pthread_create(&tid1, nullptr, Drive, nullptr);
//     pthread_create(&tid2, nullptr, Sell, nullptr);

//     pthread_join(tid1, nullptr);
//     pthread_join(tid2, nullptr);

//     return 0;
// }

// static int g_ticket = 1000;
// Sem sem(1); // 信号量
// void *Route(void *args)
// {
//     string name = static_cast<char*>(args);
//     while(true)
//     {
//         sem.P();
//         if(g_ticket > 0)
//         {
//             usleep(1000);
//             g_ticket--;
//             cout << name << ": " << g_ticket << endl;
//             sem.V();
//         }
//         else
//         {
//             sem.V();
//             break;
//         }
//     }
//     std::cout << name << " quit..." << std::endl;
// 	pthread_exit((void*)0);
// }

// int main()
// {
//     pthread_t tid1;
//     pthread_t tid2;
//     pthread_t tid3;
//     pthread_create(&tid1, nullptr, Route, (void*)"thread-1");
//     pthread_create(&tid2, nullptr, Route, (void*)"thread-2");
//     pthread_create(&tid3, nullptr, Route, (void*)"thread-3");

//     pthread_join(tid1, nullptr);
//     pthread_join(tid2, nullptr);
//     pthread_join(tid3, nullptr);

//     return 0;
// }